package br.com.petsis.funcionalidades.manterCliente;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.international.StatusMessage.Severity;

import br.com.petsis.entity.Cliente;
import br.com.petsis.entity.Empresa;
import br.com.petsis.entity.FormaPagamento;
import br.com.petsis.entity.Pedido;
import br.com.petsis.entity.Pet;
import br.com.petsis.entity.Prontuario;
import br.com.petsis.entity.Raca;
import br.com.petsis.entity.Servico;
import br.com.petsis.utilitarios.UtilContexto;

@Name("manterClienteController")
@Scope(ScopeType.CONVERSATION)
//@Restrict(value="#{identity.hasRole('Administrador')}")
public class ManterClienteController {
	
	private static final String QRY_CLIENTES = "select c.id_cliente,c.dsc_nome,c.tel_celular,c.tel_residencial,c.dsc_email from cliente c where c.id_empresa = :idEmpresa and c.flg_ativo = 'T'";
	private static final String QRY_RACAS = "select r from Raca r where r.empresa.idEmpresa = :idEmpresa and r.flgAtivo = 'T'";
	private static final String QRY_PETS = "select p from Pet p where p.cliente.empresa.idEmpresa = :idEmpresa and p.cliente.idCliente = :idCliente and p.flgAtivo = 'T'";
	private static final String QRY_PEDIDOS_CLIENTE = "select p.id_pedido,p.dta_pedido,p.vlr_pedido,p.flg_pago,p.id_forma_pagamento from pedido p where p.id_cliente = :idCliente order by p.dta_pedido DESC";
	private static final String QRY_PRONTUARIOS_CLIENTE = "select p.id_prontuario,p.dta_atendimento,p.vlr_atendimento,p.flg_pago,p.id_forma_pagamento from prontuario p where p.id_cliente = :idCliente order by p.dta_atendimento DESC";
	
	private static final String PARAMETER_ID_CLIENTE = "idCliente";
	private static final String PARAMETER_ID_EMPRESA = "idEmpresa";

	@In(create=true)
	private EntityManager entityManager;
	
	private List<Cliente> listaClientes;
	
	private Cliente clienteEdicao;
	
	private List<Raca> listaRacas;
	
	private List<Pet> listaPets;
	
	private List<Pedido> listaPedidos;
	
	private List<Prontuario> listaProntuarios;
	
	private boolean selecionadoTodos;
	
	private boolean selecionadoTodosPets;
	
	@In(required=false)
	private Empresa empresaSessao;
	
	private String filtroNome;
	
	private String filtroTelCel;
	
	private String filtroTelRes;
	
	public String getFiltroNome() {
		return filtroNome;
	}

	public void setFiltroNome(String filtroNome) {
		this.filtroNome = filtroNome;
	}

	public String getFiltroTelCel() {
		return filtroTelCel;
	}

	public void setFiltroTelCel(String filtroTelCel) {
		this.filtroTelCel = filtroTelCel;
	}

	public String getFiltroTelRes() {
		return filtroTelRes;
	}

	public void setFiltroTelRes(String filtroTelRes) {
		this.filtroTelRes = filtroTelRes;
	}
	
	public boolean filtrarClientesPorNome(Object current){
		Cliente cliente = (Cliente)current;
		if(getFiltroNome() == null || getFiltroNome().isEmpty()){
			return true;
		}
		if(cliente.getDscNome().toLowerCase().contains(getFiltroNome().toLowerCase())){
			return true;
		}else{
			return false;
		}
	}
	
	public boolean filtrarClientesPorTelCel(Object current){
		Cliente cliente = (Cliente)current;
		if(getFiltroTelCel() == null || getFiltroTelCel().isEmpty()){
			return true;
		}
		if(cliente.getTelCelular().toLowerCase().contains(getFiltroTelCel().toLowerCase())){
			return true;
		}else{
			return false;
		}
	}
	
	public boolean filtrarClientesPorTelRes(Object current){
		Cliente cliente = (Cliente)current;
		if(getFiltroTelRes() == null || getFiltroTelRes().isEmpty()){
			return true;
		}
		if(cliente.getTelResidencial().toLowerCase().contains(getFiltroTelRes().toLowerCase())){
			return true;
		}else{
			return false;
		}
	}

	public void onLoad(){
		
	}
	
	public void onLoadList(){
		clienteEdicao = new Cliente();
	}
	
	public void excluir(){
		List<Cliente> listaRemocao = new ArrayList<Cliente>();
		for(Cliente c : getListaClientes()){
			if(c.isSelecionado()){
				c.setFlgAtivo('F');
				entityManager.merge(c);
				listaRemocao.add(c);
			}
		}
		entityManager.flush();
		getListaClientes().removeAll(listaRemocao);
		setSelecionadoTodos(false);
	}
	
	public void excluirPet(){
		List<Pet> listaRemocao = new ArrayList<Pet>();
		for(Pet c : getListaPets()){
			if(c.isSelecionado()){
				if(c.getIdPet() != null){
					c.setFlgAtivo('F');
					entityManager.merge(c);
				}
				listaRemocao.add(c);
			}
		}
		entityManager.flush();
		getListaPets().removeAll(listaRemocao);
		setSelecionadoTodosPets(false);
	}
	
	public String salvar(){
		if(empresaSessao == null){
			FacesMessages.instance().add(Severity.ERROR,"Somente empresas podem cadastrar clientes");
			return null;
		}
		if(!validaEmailCliente()){
			FacesMessages.instance().add(Severity.ERROR,"E-mail já cadastrado no sistema.");
			return null;
		}
		clienteEdicao.setFlgAtivo('T');
		clienteEdicao.setEmpresa(empresaSessao);
		Cliente clienteSalvo = entityManager.merge(clienteEdicao);
		if(!getListaClientes().contains(clienteSalvo)){
			getListaClientes().add(clienteSalvo);
		}
		clienteEdicao = new Cliente();
		for(Pet p : listaPets){
			if(p.getIdRacaSelecionada() == null){
				FacesMessages.instance().add(Severity.ERROR,"Raça não encontrada. Favor, tente novamente.");
				return null;
			}
			if(p.getDscNome() == null || p.getDscNome().isEmpty()){
				continue;
			}
			Raca novaRaca = entityManager.find(Raca.class, p.getIdRacaSelecionada());
			p.setRaca(null);
			p.setRaca(novaRaca);
			p.setCliente(clienteSalvo);
			p.setPorte('P');
			p.setFlgAtivo('T');
			entityManager.merge(p);
		}
		listaPets = new ArrayList<Pet>();
		entityManager.flush();
		FacesMessages.instance().add(Severity.INFO,"Cliente salvo com sucesso.");
		return "persisted";
	}
	
	public boolean validaEmailCliente(){
		if(getClienteEdicao().getDscEmail() != null &&
				!getClienteEdicao().getDscEmail().isEmpty()){
			try{
				entityManager.createQuery("select c from Cliente c where c.flgAtivo = 'T' and UPPER(c.dscEmail) = UPPER(:email)")
					.setParameter("email", getClienteEdicao().getDscEmail())
					.getSingleResult();
				return false;
			}catch(NoResultException e){
				try{
					entityManager.createQuery("select u from Usuario u where UPPER(u.dscUsuario) = UPPER(:email) and u.flgAtivo = 'T' ")
						.setParameter("email", getClienteEdicao().getDscEmail())
						.getSingleResult();
					return false;
				}catch(NoResultException e2){
					try{
						entityManager.createQuery("select e from Empresa e where UPPER(e.dscEmail) = UPPER(:email) and e.flgAtivo = 'T' ")
							.setParameter("email", getClienteEdicao().getDscEmail())
							.getSingleResult();
						return false;
					}catch(NoResultException e3){
						return true;
					}
				}
			}
		}
		return true;
	}
	
	public String editar(Cliente cliente){
		if(empresaSessao == null){
			return null;
		}
		clienteEdicao = entityManager.find(Cliente.class, cliente.getIdCliente());
		listaPets = entityManager.createQuery(QRY_PETS)
			.setParameter(PARAMETER_ID_CLIENTE, clienteEdicao.getIdCliente())
			.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
			.getResultList();
		
		for(Pet p : listaPets){
			p.setIdRacaSelecionada(p.getRaca().getIdRaca());
			p.setNomeRacaSelecionada(p.getRaca().getDscNome());
		}
		recuperaAtendimentosCliente(clienteEdicao);
		recuperaPedidosCliente(clienteEdicao);
		return "editar";
	}
	
	public void recuperaPedidosCliente(Cliente cliente){
		List<Object[]> listaPed = entityManager.createNativeQuery(QRY_PEDIDOS_CLIENTE)
			.setParameter(PARAMETER_ID_CLIENTE, cliente.getIdCliente())
			.getResultList();
		listaPedidos = new ArrayList<Pedido>();
		Pedido p;
		FormaPagamento formaPagamento;
		for(Object[] o : listaPed){
			p = new Pedido();
			p.setIdPedido(Integer.parseInt(o[0].toString()));
			p.setDtaPedido((Date)o[1]);
			p.setVlrPedido(Float.parseFloat(o[2].toString()));
			p.setFlgPago((Character)o[3]);
			formaPagamento = new FormaPagamento();
			formaPagamento.setIdFormaPagamento(Integer.parseInt(o[4].toString()));
			formaPagamento.setDscFormaPagamento(recuperaDescricaoFormaPagamento(formaPagamento.getIdFormaPagamento()));
			p.setFormaPagamento(formaPagamento);
			listaPedidos.add(p);
		}
	}
	
	public void recuperaAtendimentosCliente(Cliente cliente){
		List<Object[]> listaAtend = entityManager.createNativeQuery(QRY_PRONTUARIOS_CLIENTE)
			.setParameter(PARAMETER_ID_CLIENTE, cliente.getIdCliente())
			.getResultList();
		listaProntuarios = new ArrayList<Prontuario>();
		Prontuario pront;
		FormaPagamento formaPagamento;
		for(Object[] o : listaAtend){
			pront = new Prontuario();
			pront.setIdProntuario(Integer.parseInt(o[0].toString()));
			pront.setDtaAtendimento((Date)o[1]);
			pront.setVlrAtendimento(Float.parseFloat(o[2].toString()));
			pront.setFlgPago((Character)o[3]);
			formaPagamento = new FormaPagamento();
			formaPagamento.setIdFormaPagamento(Integer.parseInt(o[4].toString()));
			formaPagamento.setDscFormaPagamento(recuperaDescricaoFormaPagamento(formaPagamento.getIdFormaPagamento()));
			pront.setFormaPagamento(formaPagamento);
			listaProntuarios.add(pront);
		}
	}
	
	public String recuperaDescricaoFormaPagamento(Integer id){
		try {
			Object desc = entityManager.createNativeQuery("select f.dsc_forma_pagamento from forma_pagamento f where f.id_forma_pagamento = :id")
				.setParameter("id", id)
				.getSingleResult();
			return desc != null ? desc.toString() : null;
		} catch (NoResultException e) {
			return null;
		}
	}

	public boolean isSelecionadoTodos() {
		return selecionadoTodos;
	}

	public void setSelecionadoTodos(boolean selecionadoTodos) {
		this.selecionadoTodos = selecionadoTodos;
	}
	
	public void selecionaTodos(){
		for(Cliente c : getListaClientes()){
			if(isSelecionadoTodos()){
				c.setSelecionado(true);
			}else{
				c.setSelecionado(false);
			}
		}
	}
	
	public void selecionaTodosPets(){
		for(Pet c : getListaPets()){
			if(isSelecionadoTodosPets()){
				c.setSelecionado(true);
			}else{
				c.setSelecionado(false);
			}
		}
	}

	public List<Cliente> getListaClientes() {
		if (listaClientes == null) {
			listaClientes = new ArrayList<Cliente>(); 
			if(empresaSessao != null){
				List<Object[]> lista = entityManager.createNativeQuery(QRY_CLIENTES)
					.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
					.getResultList();
				Cliente c;
				for(Object[] o : lista){
					c = new Cliente();
					c.setIdCliente(Integer.parseInt(o[0].toString()));
					c.setDscNome(o[1] != null ? o[1].toString() : null);
					c.setTelCelular(o[2] != null ? o[2].toString() : null);
					c.setTelResidencial(o[3] != null ? o[3].toString() : null);
					c.setDscEmail(o[4] != null ? o[4].toString() : null);
					listaClientes.add(c);
				}
			}
		}
		return listaClientes;
	}

	public void setListaClientes(List<Cliente> listaClientes) {
		this.listaClientes = listaClientes;
	}

	public Cliente getClienteEdicao() {
		if (clienteEdicao == null) {
			clienteEdicao = new Cliente();
		}
		return clienteEdicao;
	}

	public void setClienteEdicao(Cliente clienteEdicao) {
		this.clienteEdicao = clienteEdicao;
	}

	public List<Raca> getListaRacas() {
		if (listaRacas == null) {
			if(empresaSessao != null){
				return entityManager.createQuery(QRY_RACAS)
					.setParameter(PARAMETER_ID_EMPRESA, empresaSessao.getIdEmpresa())
					.getResultList();
				/*List<Raca> racas = entityManager.createQuery(QRY_RACAS).getResultList();
				listaRacas = new ArrayList<SelectItem>();
				listaRacas.add(new SelectItem(null,"Selecione"));
				for(Raca r : racas){
					listaRacas.add(new SelectItem(r.getIdRaca(),r.getDscNome()));
				}*/
			}
		}
		return listaRacas;
	}

	public void setListaRacas(List<Raca> listaRacas) {
		this.listaRacas = listaRacas;
	}

	public List<Pet> getListaPets() {
		if (listaPets == null) {
			listaPets = new ArrayList<Pet>();
		}
		return listaPets;
	}

	public void setListaPets(List<Pet> listaPets) {
		this.listaPets = listaPets;
	}
	
	public List<Pedido> getListaPedidos() {
		if (listaPedidos == null) {
			listaPedidos = new ArrayList<Pedido>();
		}
		return listaPedidos;
	}

	public void setListaPedidos(List<Pedido> listaPedidos) {
		this.listaPedidos = listaPedidos;
	}

	public List<Prontuario> getListaProntuarios() {
		if (listaProntuarios == null) {
			listaProntuarios = new ArrayList<Prontuario>();
		}
		return listaProntuarios;
	}

	public void setListaProntuarios(List<Prontuario> listaProntuarios) {
		this.listaProntuarios = listaProntuarios;
	}

	public void novoPet(){
		getListaPets().add(new Pet(new Raca()));
	}
	
	public String novoCliente(){
		return "novo"; 
	}
	
	public String cancelar(){
		clienteEdicao = new Cliente();
		listaPets = new ArrayList<Pet>();
		return "voltar";  
	}
	
	public List<Raca> autocomplete(Object suggest) {
        String pref = (String)suggest;
        List<Raca> result = new ArrayList<Raca>();

        Iterator<Raca> iterator = getListaRacas().iterator();
        while (iterator.hasNext()) {
            Raca elem = ((Raca) iterator.next());
            if ((elem.getDscNome() != null && elem.getDscNome().toLowerCase().indexOf(pref.toLowerCase()) == 0) || "".equals(pref))
            {
                result.add(elem);
            }
        }
        return result;
	}

	public boolean isSelecionadoTodosPets() {
		return selecionadoTodosPets;
	}

	public void setSelecionadoTodosPets(boolean selecionadoTodosPets) {
		this.selecionadoTodosPets = selecionadoTodosPets;
	}
	
	public String montaUrlClientes(){
		if(empresaSessao != null){
			return UtilContexto.recuperaUrlAplicacao().replace("clienteList.seam", "")+"novoCliente.seam?empresa="+empresaSessao.getIdEmpresa()*1250;
		}else{
			return null;
		}
	}
}
